package com.tianxiao.faas.biz.service.corner;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.tianxiao.faas.api.param.corner.BasePageParam;
import com.tianxiao.faas.api.param.corner.BazaarApplyPageParam;
import com.tianxiao.faas.api.param.corner.BazaarApplyParam;
import com.tianxiao.faas.api.param.corner.BazaarApplyResult;
import com.tianxiao.faas.api.param.corner.BazaarParam;
import com.tianxiao.faas.api.param.corner.BazaarResult;
import com.tianxiao.faas.biz.corner.service.user.UserService;
import com.tianxiao.faas.common.exception.biz.BizException;
import com.tianxiao.faas.common.result.Result;
import com.tianxiao.faas.common.util.Base64Utils;
import com.tianxiao.faas.common.util.DateUtils;
import com.tianxiao.faas.common.util.LikeQueryUtils;
import com.tianxiao.faas.common.util.PageUtils;
import com.tianxiao.faas.common.util.StringUtils;
import com.tianxiao.faas.mapper.dao.ActivityApplyModelMapper;
import com.tianxiao.faas.mapper.dao.ActivityModelMapper;
import com.tianxiao.faas.mapper.dao.ShopModelMapper;
import com.tianxiao.faas.mapper.model.*;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ActivityService {
    @Resource
    private ActivityModelMapper activityModelMapper;
    @Resource
    private ActivityApplyModelMapper activityApplyModelMapper;
    @Resource
    private ShopModelMapper shopModelMapper;
    @Resource
    private UserService userService;
    @Resource
    private ShopService shopService;

    public BazaarResult get(Long id, Long userId) {
        ActivityModel activityModel = activityModelMapper.selectByPrimaryKey(id);
        if (activityModel == null) {
            return null;
        }
        BazaarResult bazaarResult = getBazaarResult(activityModel, System.currentTimeMillis());
        String content = activityModel.getContent();
        if (content != null) {
            String decode = Base64Utils.decode(content);
            bazaarResult.setContent(decode);
        }
        if (userId != null) {
            ShopModel shopModel = shopModelMapper.selectByUserId(userId);
            if (shopModel != null) {
                ActivityApplyModelExample example = new ActivityApplyModelExample();
                example.createCriteria().andShopIdEqualTo(shopModel.getId()).andActivityIdEqualTo(id).andDeletedEqualTo(0);
                List<ActivityApplyModel> applyModels = activityApplyModelMapper.selectByExample(example);
                bazaarResult.setJoined(!CollectionUtils.isEmpty(applyModels));
            }
        }
        return bazaarResult;
    }

    public void save(BazaarParam param) {
        Long id = param.getId();
        long currentTimeMillis = System.currentTimeMillis();
        ActivityModel activityModel = new ActivityModel();
        activityModel.setAddress(param.getAddress());
        activityModel.setUpdated(currentTimeMillis);
        if (param.getUrl() != null) {
            activityModel.setImg(JSON.toJSONString(param.getUrl()));
        }
        activityModel.setName(param.getName());
        activityModel.setStartTime(DateUtils.format(param.getBeginTime()));
        activityModel.setEndTime(DateUtils.format(param.getEndTime()));
        activityModel.setScan(param.getScan());
        String content = param.getContent();
        if (content != null) {
            activityModel.setContent(Base64Utils.encode(content));
        }
        if (id == null) {
            activityModel.setCreated(currentTimeMillis);
            activityModel.setDeleted(0);
            activityModelMapper.insertSelective(activityModel);
        } else {
            ActivityModel db = activityModelMapper.selectByPrimaryKey(id);
            if (db == null) {
                throw new BizException("更新集市不存在");
            }
            activityModel.setId(param.getId());
            activityModelMapper.updateByPrimaryKeySelective(activityModel);
        }
    }

    public List<BazaarResult> listCanJoinBazaar(Long userId) {
        ShopModel shopModel = shopModelMapper.selectByUserId(userId);
        if (shopModel == null) {
            throw new BizException("未开店，不可报名哦");
        }
        long currentTimeMillis = System.currentTimeMillis();
        ActivityApplyModelExample applyModelExample = new ActivityApplyModelExample();
        applyModelExample.createCriteria().andShopIdEqualTo(shopModel.getId()).andDeletedEqualTo(0);
        List<ActivityApplyModel> activityApplyModels = activityApplyModelMapper.selectByExample(applyModelExample);
        Map<Long, ActivityApplyModel> activityApplyModelMap = activityApplyModels.stream().collect(Collectors.toMap(ActivityApplyModel::getActivityId, s -> s));
        ActivityModelExample example = new ActivityModelExample();
        example.createCriteria().andDeletedEqualTo(0).andStartTimeGreaterThan(currentTimeMillis);
        example.setOrderByClause("updated desc");
        List<ActivityModel> activityModels = activityModelMapper.selectByExample(example);
        List<BazaarResult> bazaarResults = new ArrayList<>();
        for (ActivityModel activityModel : activityModels) {
            ActivityApplyModel activityApplyModel = activityApplyModelMap.get(activityModel.getId());
            if (activityApplyModel != null) {
                continue;
            }
            BazaarResult bazaarResult = getBazaarResult(activityModel, currentTimeMillis);
            bazaarResults.add(bazaarResult);
        }
        return bazaarResults;
    }

    public List<BazaarResult> listJoinBazaar(Long userId, Integer page, Integer pageSize, Integer status) {
        ShopModel shopModel = shopModelMapper.selectByUserId(userId);
        if (shopModel == null) {
            throw new BizException("未开店，不可报名哦");
        }
        List<BazaarResult> bazaarResults = new ArrayList<>();
        List<Long> activityIds = activityApplyModelMapper.listActivityIdByShopId(shopModel.getId(), PageUtils.getOffset(page, pageSize), pageSize, status);
        if (CollectionUtils.isEmpty(activityIds)) {
            return bazaarResults;
        }
        List<ActivityModel> activityModels = activityModelMapper.query(activityIds);
        Map<Long, ActivityModel> activityModelMap = activityModels.stream().collect(Collectors.toMap(ActivityModel::getId, s -> s));

        long currentTimeMillis = System.currentTimeMillis();
        for (Long activityId : activityIds) {
            ActivityModel activityModel = activityModelMap.get(activityId);
            BazaarResult bazaarResult = getBazaarResult(activityModel, currentTimeMillis);
            bazaarResults.add(bazaarResult);
        }
        return bazaarResults;
    }

    private BazaarResult getBazaarResult(ActivityModel activityModel, Long currentTime) {
        BazaarResult bazaarResult = new BazaarResult();
        bazaarResult.setAddress(activityModel.getAddress());
        bazaarResult.setAddress(activityModel.getAddress());
        bazaarResult.setId(activityModel.getId());
        bazaarResult.setImg(JSON.parseArray(activityModel.getImg(), String.class));
        bazaarResult.setName(activityModel.getName());
        bazaarResult.setScan(activityModel.getScan());
        Long startTime = activityModel.getStartTime();
        bazaarResult.setBeginTime(DateUtils.format(startTime, DateUtils.yyyy_M_d));
        Long endTime = activityModel.getEndTime();
        bazaarResult.setEndTime(DateUtils.format(endTime, DateUtils.yyyy_M_d));
        int status = 2;
        String statusStr = "未开始";
        if (startTime != null && endTime != null) {
            if (currentTime >= startTime && currentTime < endTime) {
                status = 1;
                statusStr = "已开始";
            } else if (currentTime >= endTime) {
                status = 3;
                statusStr = "已结束";
            }
        }
        bazaarResult.setStatus(status);
        bazaarResult.setStatusStr(statusStr);
        return bazaarResult;
    }

    public Integer count(BasePageParam param, Long now) {
        String key = param.getKey();
        key = LikeQueryUtils.getKey(key);
        Integer count = activityModelMapper.count(key,now);
        return count == null ? 0 : count;
    }

    public void checkJoined(List<BazaarResult> results, Long userId) {
        if (userId != null) {
            ShopModel shop = shopService.getByUserId(userId);
            if (shop != null) {
                List<Long> activityIds = activityApplyModelMapper.queryByShopId(shop.getId());
                if (!CollectionUtils.isEmpty(activityIds)) {
                    for (BazaarResult result : results) {
                        if (activityIds.contains(result.getId())) {
                            result.setJoined(true);
                        }
                    }
                }
            }
        }
    }

    public List<BazaarResult> list(BasePageParam param, Long now) {
        String key = param.getKey();
        key = LikeQueryUtils.getKey(key);
        Long startTime = DateUtils.format(param.getBeginTime());
        Long endTime = DateUtils.format(param.getEndTime());
        List<ActivityModel> activityModels = activityModelMapper.list(key, now, startTime, endTime, PageUtils.getOffset(param.getPage(), param.getPageSize()), param.getPageSize());
        List<BazaarResult> bazaarResults = new ArrayList<>();
        long currentTimeMillis = System.currentTimeMillis();
        for (ActivityModel activityModel : activityModels) {
            BazaarResult bazaarResult = getBazaarResult(activityModel, currentTimeMillis);
            bazaarResults.add(bazaarResult);
        }
        return bazaarResults;
    }

    public void apply(BazaarApplyParam bazaarApplyParam, Long userId) {
        ShopModel shopModel = shopModelMapper.selectByUserId(userId);
        if (shopModel == null) {
            throw new BizException("店铺不存在，请先开店铺哦");
        }
        Long bazaarId = bazaarApplyParam.getBazaarId();
        ActivityModel activityModel = activityModelMapper.selectByPrimaryKey(bazaarId);
        if (activityModel == null) {
            throw new BizException("报名的集市信息不存在");
        }
        long currentTime = System.currentTimeMillis();
        BazaarResult bazaarResult = getBazaarResult(activityModel, currentTime);
        int status = bazaarResult.getStatus();
        if (status == 3) {
            throw new BizException("报名的集市已结束");
        }
        ActivityApplyModel record = new ActivityApplyModel();
        record.setActivityId(bazaarId);
        record.setApplyStatus(0);
        record.setDeleted(0);
        String mobile = bazaarApplyParam.getMobile();
        UsersModel user = userService.getById(userId);
        if (StringUtils.isEmpty(mobile)) {
            mobile = user.getMobile();
            bazaarApplyParam.setMobile(mobile);
        }
        String name = bazaarApplyParam.getName();
        if (StringUtils.isEmpty(name)) {
            name = user.getName();
            bazaarApplyParam.setMobile(name);
        }
        String shopName = bazaarApplyParam.getShopName();
        if (StringUtils.isEmpty(shopName)) {
            bazaarApplyParam.setShopName(shopModel.getName());
        }
        record.setMobile(mobile);
        record.setCreated(currentTime);
        record.setShopId(shopModel.getId());
        record.setUpdated(currentTime);
        record.setValueBox(JSON.toJSONString(bazaarApplyParam));
        try {
            activityApplyModelMapper.insertSelective(record);
        } catch (DuplicateKeyException e) {
            throw new BizException("你已报名过了哦");
        }

    }

    public Result<List<BazaarApplyResult>> pageShopByBazaarId(BazaarApplyPageParam param) {
        Long bazaarId = param.getBazaarId();
        List<Long> activityIds = null;
        if (bazaarId != null) {
            activityIds = Lists.newArrayList(bazaarId);
        }
        if (param.getBeginTime() != null && param.getEndTime() != null) {
            Long begin = DateUtils.format(param.getBeginTime());
            Long end = DateUtils.format(param.getEndTime());
            ActivityModelExample example = new ActivityModelExample();
            example.createCriteria().andStartTimeGreaterThanOrEqualTo(begin)
                    .andStartTimeLessThanOrEqualTo(end).andDeletedEqualTo(0);
            List<ActivityModel> activityModels = activityModelMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(activityModels)) {
                activityIds = activityModels.stream().map(ActivityModel::getId).collect(Collectors.toList());
            }
        }
        Integer pageSize = param.getPageSize();
        Integer page = param.getPage();
        List<BazaarApplyResult> data = Lists.newArrayList();
        Result result = Result.builder().success(true).pageNo(page).data(data).pageSize(pageSize);
        Integer offset = PageUtils.getOffset(page, pageSize);
        Integer status = param.getApplyStatus();
        List<ActivityApplyModel> applyModels = activityApplyModelMapper.page(activityIds, status, offset, pageSize);
        if (CollectionUtils.isEmpty(applyModels)) {
            return result;
        }
        List<Long> actIds = applyModels.stream().map(ActivityApplyModel::getActivityId).collect(Collectors.toList());
        List<Long> shopIds = applyModels.stream().map(ActivityApplyModel::getShopId).collect(Collectors.toList());
        ActivityModelExample example = new ActivityModelExample();
        example.createCriteria().andIdIn(actIds).andDeletedEqualTo(0);
        List<ActivityModel> activityModels = activityModelMapper.selectByExample(example);
        Map<Long, ActivityModel> activityModelMap = activityModels.stream()
                .collect(Collectors.toMap(ActivityModel::getId, s -> s, (key1, key2) -> key1));
        ShopModelExample example1 = new ShopModelExample();
        example1.createCriteria().andIdIn(shopIds).andDeletedEqualTo(0);

//        List<ShopModel> shopModels = shopModelMapper.selectByExample(example1);
//        Map<Long, ShopModel> shopModelMap = shopModels.stream()
//                .collect(Collectors.toMap(ShopModel::getId, s -> s, (key1, key2) -> key1));

        Integer count = activityApplyModelMapper.count(activityIds, status);
        for (ActivityApplyModel applyModel : applyModels) {
            BazaarApplyResult bazaarApplyResult = new BazaarApplyResult();
            Integer applyStatus = applyModel.getApplyStatus();
            String str = getApplyStatusStr(applyStatus);
            bazaarApplyResult.setApplyStatus(applyStatus);
            bazaarApplyResult.setApplyStatusStr(str);
            bazaarApplyResult.setApplyTime(DateUtils.format(applyModel.getCreated()));
            Long activityId = applyModel.getActivityId();
            bazaarApplyResult.setBazaarId(activityId);
            ActivityModel activityModel = activityModelMap.get(activityId);
            if (activityModel != null) {
                bazaarApplyResult.setBeginTime(DateUtils.format(activityModel.getStartTime()));
                bazaarApplyResult.setEndTime(DateUtils.format(activityModel.getEndTime()));
                bazaarApplyResult.setName(activityModel.getName());
                bazaarApplyResult.setUrl(activityModel.getImg());
            }
            Long shopId = applyModel.getShopId();
            bazaarApplyResult.setShopId(shopId);
            String valueBox = applyModel.getValueBox();
            BazaarApplyParam bazaarApplyParam = JSON.parseObject(valueBox, BazaarApplyParam.class);
            bazaarApplyResult.setShopName(bazaarApplyParam.getShopName());
            bazaarApplyResult.setShopMobile(bazaarApplyParam.getMobile());
            bazaarApplyResult.setId(applyModel.getId());
            data.add(bazaarApplyResult);
        }

        return result.totalCount(count).totalPage();
    }

    private String getApplyStatusStr(Integer applyStatus) {
        String str = applyStatus == 0 ? "审核中" : applyStatus == 1 ? "成功" : "失败";
        return str;
    }

    public void audit(Long id, Integer pass) {
        if (pass != 1 && pass != 2) {
            throw new BizException("审核参数不正确");
        }
        ActivityApplyModel record = new ActivityApplyModel();
        record.setId(id);
        record.setApplyStatus(pass);
        activityApplyModelMapper.updateByPrimaryKeySelective(record);
    }

    public void delete(Long id) {
        ActivityApplyModel record = new ActivityApplyModel();
        record.setId(id);
        record.setDeleted(1);
        activityApplyModelMapper.updateByPrimaryKeySelective(record);
    }
}
